package main

import "fmt"

type Aggregate interface {
	Iterator() Iterator
}

type Iterator interface {
	First()
	IsDone() bool
	Next() interface{}
}

type Numbers struct {
	start, end int
}

func NewNumbers(start, end int) *Numbers {
	return &Numbers{
		start: start,
		end:   end,
	}
}

func (n *Numbers) Iterator() Iterator {
	return &NumbersIterator{
		numbers: n,
		next:    n.start,
	}
}

type NumbersIterator struct {
	numbers *Numbers
	next    int
}

func (i *NumbersIterator) First() {
	i.next = i.numbers.start
}

func (i *NumbersIterator) IsDone() bool {
	return i.next > i.numbers.end
}

func (i *NumbersIterator) Next() interface{} {
	if !i.IsDone() {
		next := i.next
		i.next++
		return next
	}
	return nil
}

func IteratorPrint(i Iterator) {
	for i.First(); !i.IsDone(); {
		c := i.Next()
		fmt.Printf("%#v\n", c)
	}
}

func main() {
	var aggregate Aggregate
	aggregate = NewNumbers(1, 10)

	IteratorPrint(aggregate.Iterator())
}

/*
送代器模式

迭代器（Iterator）模式的定义：提供一个对象来顺序访问聚合对象中的一系列数据，而不暴露聚合对象的内部表示。迭代器模式是一种对象行为型模式。

其主要优点：
	访问一个聚合对象的内容而无须暴露它的内部表示。
	遍历任务交由迭代器完成，这简化了聚合类。
	它支持以不同方式遍历一个聚合，甚至可以自定义迭代器的子类以支持新的遍历。
	增加新的聚合类和迭代器类都很方便，无须修改原有代码。
	封装性良好，为遍历不同的聚合结构提供一个统一的接口。

其主要缺点是：
	增加了类的个数，这在一定程度上增加了系统的复杂性。


# 送代器模式

送代器模式用于使用相同方式送代不同类型集合或者隐藏集合类型的具体实现。

可以使用送代器模式使遍历同时应用送代策略，如请求新对象、过滤、处理对象等。

*/
